package edu.umd.ion.wavemeter.server;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

import edu.umd.ion.wavemeter.service.PatternData;

/**
 * Wrapper class for the library functions exported by the DLL of the Wavemeter.
 * Most of the functions are implemented within the JNI native library.
 * @author monroe-lab
 *
 */
public class WavemeterLibrary {
	// *********** Testing routines *****************************************
	
	/**
	 * used for debugging the library 
	 */
	public static native int testfunction();
	
	/**
	 * used for debugging the library
	 * @return
	 */
	public static native int rand();
	

	// *********** The new TaskQueue Mechanism ******************************

	private ArrayBlockingQueue<WLMEvent> TaskQueue;
	
	public WavemeterLibrary() {
		TaskQueue = new ArrayBlockingQueue<WLMEvent>(1000);
	}

	public native int EnableJavaCallback();
	
	public native int DisableJavaCallback();
	
	public WLMEvent poll() {
		return TaskQueue.poll();
	}
	
	public WLMEvent poll(long timeout, TimeUnit Unit) throws InterruptedException {
		return TaskQueue.poll(timeout, Unit);
	}
	
	public WLMEvent remove() {
		return TaskQueue.remove();
	}

	public void JavaCallback( int Version, int Mode, int IntVal, double DoubleVal, int Res1 ) {
		TaskQueue.offer(new WLMEvent( Version, Mode, IntVal, DoubleVal, Res1 ));
	}
	
	public int size() { 
		return TaskQueue.size();
	}

	// ***********  Functions for general usage  ****************************
	public static native int Instantiate(int RFC, int Mode, int P1, int P2) ;
	public static native int ControlWLM(int Action, int App, int Res1) ;
	public static native int ControlWLMEx(int Action, int App, int Ver, int Ex1, int Ex2) ;
	public static native int SetMeasurementDelayMethod(int Mode, int Delay)	;
	public static native int SetWLMPriority(int PPC, int Res1, int Res2) ;
	public static native int PresetWLMIndex(int Ver) ;

	public static native int GetWLMVersion(int Ver) ;
	public static native int GetWLMIndex(int Ver) ;
	public static native int GetWLMCount(int V) ;
	
	// ***********  Get...-functions  ***************************************
	public static native double GetWavelength(double WL) ;
	public static native double GetWavelength2(double WL2) ;
	public static native double GetWavelengthNum(int num, double WL) ;
	public static native double GetCalWavelength(int ba, double WL) ;
	public static native double GetFrequency(double F) ;
	public static native double GetFrequency2(double F2) ;
	public static native double GetFrequencyNum(int num, double F) ;
	public static native double GetDistance(double D) ;
	public static native double GetAnalogIn(double AI) ;
	public static native double GetTemperature(double T) ;
	public static native int SetTemperature(double T) ;

	public static native int GetExposure(int E) ;
	public static native int SetExposure(int E) ;
	public static native int GetExposure2(int E2) ;
	public static native int SetExposure2(int E2) ;
	public static native int GetExposureNum(int num, int arr, int E) ;
	public static native int SetExposureNum(int num, int arr, int E) ;
	public static native boolean GetExposureMode(boolean EM) ;
	public static native int SetExposureMode(boolean EM) ;
	public static native int GetExposureModeNum(int num, boolean EM) ;
	public static native int SetExposureModeNum(int num, boolean EM) ;
	public static native int GetExposureRange(int ER) ;

	public static native int GetResultMode(int RM) ;
	public static native int SetResultMode(int RM) ;
	public static native int GetRange(int R) ;
	public static native int SetRange(int R) ;
	public static native int GetPulseMode(int PM) ;
	public static native int SetPulseMode(int PM) ;
	public static native int GetWideMode(int WM) ;
	public static native int SetWideMode(int WM) ;

	public static native int GetDisplayMode(int DM) ;
	public static native int SetDisplayMode(int DM) ;
	public static native boolean GetFastMode(boolean FM) ;
	public static native int SetFastMode(boolean FM) ;

	public static native int GetSwitcherMode(int SM);
	public static native int SetSwitcherMode(int SM) ;
	public static native int GetSwitcherChannel(int CH) ;
	public static native int SetSwitcherChannel(int CH) ;
	public static native int GetSwitcherSignalStates(int Signal, SwitcherSignalState State);
	public static native int SetSwitcherSignalStates(int Signal, int Use, int Show);
	public static native int SetSwitcherSignal(int Signal, int Use, int Show) ;

	public static native int GetAutoCalMode(int ACM) ;
	public static native int SetAutoCalMode(int ACM) ;
	public static native int GetAutoCalSetting(int ACS, int val, int Res1, int Res2) ;
	public static native int SetAutoCalSetting(int ACS, int val, int Res1, int Res2) ;

	public static native int GetActiveChannel(int Mode, Integer Port, int Res1) ;
	public static native int SetActiveChannel(int Mode, int Port, int CH, int Res1) ;
	public static native int GetChannelsCount(int C) ;

	
	public static native int GetOperationState(int Op) ;
	public static native int Operation(int Op) ;
	public static native int SetOperationFile(String File) ;
	public static native int Calibration(int Type, int Unit, double Value, int Channel) ;
	public static native int RaiseMeasurementEvent(int Mode) ;
	public static native int TriggerMeasurement(int Action) ;

	public static native boolean GetLinkState(boolean LS) ;
	public static native int SetLinkState(boolean LS) ;
	public static native void LinkSettingsDlg() ;

	public static native int GetPatternItemSize(int Index) ;
	public static native int GetPatternItemCount(int Index) ;
	public static native int GetPattern(int Index) ;
	public static native int GetPatternNum(int Chn, int Index) ;
	public static native PatternData GetPatternDataNum( PatternData data );
	public static native int SetPattern(int Index, int iEnable) ;
	public static native int SetPatternData(int Index, long PArray) ;

	public static native int GetAnalysisMode(boolean AM) ;
	public static native int SetAnalysisMode(boolean AM) ;
	public static native int GetAnalysisItemSize(int Index) ;
	public static native int GetAnalysisItemCount(int Index) ;
	public static native int GetAnalysis(int Index) ;
	public static native int GetAnalysisData(int Index, long PArray) ;
	public static native int SetAnalysis(int Index, int iEnable) ;
	public static native double GetLinewidth(int Index, double LW) ;

	public static native int GetMinPeak(int M1) ;
	public static native int GetMinPeak2(int M2) ;
	public static native int GetMaxPeak(int X1) ;
	public static native int GetMaxPeak2(int X2) ;
	public static native int GetAvgPeak(int A1) ;
	public static native int GetAvgPeak2(int A2) ;
	public static native int SetAvgPeak(int PA) ;

	public static native int GetAmplitudeNum(int num, int Index, int A) ;
	public static native double GetIntensityNum(int num, double I) ;
	public static native double GetPowerNum(int num, double P) ;

	public static native int GetDelay(int D) ;
	public static native int SetDelay(int D) ;
	public static native int GetShift(int S) ;
	public static native int SetShift(int S) ;
	public static native int GetShift2(int S2) ;
	public static native int SetShift2(int S2) ;


// ***********  Deviation (Laser Control) and PID-functions  ************
	public static native boolean GetDeviationMode(boolean DM) ;
	public static native int SetDeviationMode(boolean DM) ;
	public static native double GetDeviationReference(double DR) ;
	public static native int SetDeviationReference(double DR) ;
	public static native int GetDeviationSensitivity(int DS) ;
	public static native int SetDeviationSensitivity(int DS) ;
	public static native double GetDeviationSignal(double DS) ;
	public static native double GetDeviationSignalNum(int Port, double DS) ;
	public static native int SetDeviationSignal(double DS) ;
	public static native int SetDeviationSignalNum(int Port, double DS) ;
	public static native double RaiseDeviationSignal(int iType, double dSignal);
	
	public static native String GetPIDCourse() ;
	public static native int SetPIDCourse(String PIDC) ;
	public static native String GetPIDCourseNum(int Port);
	public static native int SetPIDCourseNum(int Port, String PIDC);

	public static native int GetPIDSetting(PIDHardwareSetting Setting) ;
	public static native int SetPIDSetting(PIDHardwareSetting Setting) ;
	public static native int ClearPIDHistory(int Port) ;


// ***********  Other...-functions  *************************************
	public static native double ConvertUnit(double Val, int uFrom, int uTo) ;
	public static native double ConvertDeltaUnit(double Base, double Delta, int uBase, 
	                                  int uFrom, int uTo) ;

	static {
		System.loadLibrary("WavemeterLibrary");
	}
	
	// ***********  Constants  **********************************************

	// Instantiating Constants for 'RFC' parameter
		public static final int	cInstCheckForWLM = -1;
		public static final int	cInstResetCalc = 0;
		public static final int	cInstReturnMode = 0;
		public static final int	cInstNotification = 1;
		public static final int	cInstCopyPattern = 2;
		public static final int	cInstCopyAnalysis = 2;
		public static final int	cInstControlWLM = 3;
		public static final int	cInstControlDelay = 4;
		public static final int	cInstControlPriority = 5;

	// Notification Constants for 'Mode' parameter
		public static final int	cNotifyInstallCallback = 0;
		public static final int	cNotifyRemoveCallback = 1;
		public static final int	cNotifyInstallWaitEvent = 2;
		public static final int	cNotifyRemoveWaitEvent = 3;
		public static final int	cNotifyInstallCallbackEx = 4;
		public static final int	cNotifyInstallWaitEventEx = 5;

	// ResultError Constants of Set...-functions
		public static final int	ResERR_NoErr = 0;
		public static final int	ResERR_WlmMissing = -1;
		public static final int	ResERR_CouldNotSet = -2;
		public static final int	ResERR_ParmOutOfRange = -3;
		public static final int	ResERR_WlmOutOfResources = -4;
		public static final int	ResERR_WlmInternalError = -5;
		public static final int	ResERR_NotAvailable = -6;
		public static final int	ResERR_WlmBusy = -7;
		public static final int	ResERR_NotInMeasurementMode = -8;
		public static final int	ResERR_OnlyInMeasurementMode = -9;
		public static final int	ResERR_ChannelNotAvailable = -10;
		public static final int	ResERR_ChannelTemporarilyNotAvailable = -11;
		public static final int	ResERR_CalOptionNotAvailable = -12;
		public static final int	ResERR_CalWavelengthOutOfRange = -13;
		public static final int	ResERR_BadCalibrationSignal = -14;
		public static final int	ResERR_UnitNotAvailable = -15;

	// Mode Constants for Callback-Export and WaitForWLMEvent-function
		public static final int	cmiResultMode = 1;
		public static final int	cmiRange = 2;
		public static final int	cmiPulseMode = 3;
		public static final int	cmiWideMode = 4;
		public static final int	cmiFastMode = 5;
		public static final int	cmiExposureMode = 6;
		public static final int	cmiExposureValue1 = 7;
		public static final int	cmiExposureValue2 = 8;
		public static final int	cmiDelay = 9;
		public static final int	cmiShift = 10;
		public static final int	cmiShift2 = 11;
		public static final int	cmiReduced = 12;
		public static final int	cmiReduce = 12;
		public static final int	cmiScale = 13;
		public static final int	cmiTemperature = 14;
		public static final int	cmiLink = 15;
		public static final int	cmiOperation = 16;
		public static final int	cmiDisplayMode = 17;
		public static final int	cmiPattern1a = 18;
		public static final int	cmiPattern1b = 19;
		public static final int	cmiPattern2a = 20;
		public static final int	cmiPattern2b = 21;
		public static final int	cmiMin1 = 22;
		public static final int	cmiMax1 = 23;
		public static final int	cmiMin2 = 24;
		public static final int	cmiMax2 = 25;
		public static final int	cmiNowTick = 26;
		public static final int	cmiCallback = 27;
		public static final int	cmiFrequency1 = 28;
		public static final int	cmiFrequency2 = 29;
		public static final int	cmiDLLDetach = 30;
		public static final int	cmiVersion = 31;
		public static final int	cmiAnalysisMode = 32;
		public static final int	cmiDeviationMode = 33;
		public static final int	cmiDeviationReference = 34;
		public static final int	cmiDeviationSensitivity = 35;
		public static final int	cmiAppearance = 36;
		public static final int	cmiAutoCalMode = 37;
		public static final int	cmiWavelength1 = 42;
		public static final int	cmiWavelength2 = 43;
		public static final int	cmiLinewidth = 44;
		public static final int	cmiLinkDlg = 56;
		public static final int	cmiAnalysis = 57;
		public static final int	cmiAnalogIn = 66;
		public static final int   cmiAnalogOut = 67;
		public static final int	cmiDistance = 69;
		public static final int	cmiWavelength3 = 90;
		public static final int	cmiWavelength4 = 91;
		public static final int	cmiWavelength5 = 92;
		public static final int	cmiWavelength6 = 93;
		public static final int	cmiWavelength7 = 94;
		public static final int	cmiWavelength8 = 95;
		public static final int	cmiVersion0 = 31;
		public static final int	cmiVersion1 = 96;
		public static final int	cmiDLLAttach = 121;
		public static final int	cmiSwitcherSignal = 123;
		public static final int	cmiSwitcherMode = 124;
		public static final int	cmiExposureValue11 = 7;
		public static final int	cmiExposureValue12 = 125;
		public static final int	cmiExposureValue13 = 126;
		public static final int	cmiExposureValue14 = 127;
		public static final int	cmiExposureValue15 = 128;
		public static final int	cmiExposureValue16 = 129;
		public static final int	cmiExposureValue17 = 130;
		public static final int	cmiExposureValue18 = 131;
		public static final int	cmiExposureValue21 = 8;
		public static final int	cmiExposureValue22 = 132;
		public static final int	cmiExposureValue23 = 133;
		public static final int	cmiExposureValue24 = 134;
		public static final int	cmiExposureValue25 = 135;
		public static final int	cmiExposureValue26 = 136;
		public static final int	cmiExposureValue27 = 137;
		public static final int	cmiExposureValue28 = 138;
		public static final int	cmiPatternAverage = 139;
		public static final int	cmiPatternAvg1 = 140;
		public static final int	cmiPatternAvg2 = 141;
		public static final int	cmiAnalogOut1 = 67;
		public static final int	cmiAnalogOut2 = 142;
		public static final int	cmiMin11 = 22;
		public static final int	cmiMin12 = 146;
		public static final int	cmiMin13 = 147;
		public static final int	cmiMin14 = 148;
		public static final int	cmiMin15 = 149;
		public static final int	cmiMin16 = 150;
		public static final int	cmiMin17 = 151;
		public static final int	cmiMin18 = 152;
		public static final int	cmiMin21 = 24;
		public static final int	cmiMin22 = 153;
		public static final int	cmiMin23 = 154;
		public static final int	cmiMin24 = 155;
		public static final int	cmiMin25 = 156;
		public static final int	cmiMin26 = 157;
		public static final int	cmiMin27 = 158;
		public static final int	cmiMin28 = 159;
		public static final int	cmiMax11 = 23;
		public static final int	cmiMax12 = 160;
		public static final int	cmiMax13 = 161;
		public static final int	cmiMax14 = 162;
		public static final int	cmiMax15 = 163;
		public static final int	cmiMax16 = 164;
		public static final int	cmiMax17 = 165;
		public static final int	cmiMax18 = 166;
		public static final int	cmiMax21 = 25;
		public static final int	cmiMax22 = 167;
		public static final int	cmiMax23 = 168;
		public static final int	cmiMax24 = 169;
		public static final int	cmiMax25 = 170;
		public static final int	cmiMax26 = 171;
		public static final int	cmiMax27 = 172;
		public static final int	cmiMax28 = 173;
		public static final int	cmiAvg11 = 140;
		public static final int	cmiAvg12 = 174;
		public static final int	cmiAvg13 = 175;
		public static final int	cmiAvg14 = 176;
		public static final int	cmiAvg15 = 177;
		public static final int	cmiAvg16 = 178;
		public static final int	cmiAvg17 = 179;
		public static final int	cmiAvg18 = 180;
		public static final int	cmiAvg21 = 141;
		public static final int	cmiAvg22 = 181;
		public static final int	cmiAvg23 = 182;
		public static final int	cmiAvg24 = 183;
		public static final int	cmiAvg25 = 184;
		public static final int	cmiAvg26 = 185;
		public static final int	cmiAvg27 = 186;
		public static final int	cmiAvg28 = 187;
		public static final int	cmiPatternAnalysisWritten = 202;
		public static final int	cmiSwitcherChannel = 203;
		public static final int	cmiAnalogOut3 = 237;
		public static final int	cmiAnalogOut4 = 238;
		public static final int	cmiAnalogOut5 = 239;
		public static final int	cmiAnalogOut6 = 240;
		public static final int	cmiAnalogOut7 = 241;
		public static final int	cmiAnalogOut8 = 242;
		public static final int	cmiIntensity = 251;
		public static final int	cmiPower = 267;
		public static final int	cmiPIDCourse = 1030;
		public static final int	cmiPIDUseT = 1031;
		public static final int	cmiPID_T = 1033;
		public static final int	cmiPID_P = 1034;
		public static final int	cmiPID_I = 1035;
		public static final int	cmiPID_D = 1036;
		public static final int	cmiDeviationSensitivityDim = 1040;
		public static final int	cmiDeviationSensitivityFactor = 1037;
		public static final int	cmiDeviationPolarity = 1038;
		public static final int	cmiDeviationSensitivityEx = 1039;
		public static final int	cmiDeviationUnit = 1041;
		public static final int	cmiPIDConstdt = 1059;
		public static final int	cmiPID_dt = 1060;
		public static final int	cmiPID_AutoClearHistory = 1061;
		public static final int	cmiAutoCalPeriod = 1120;
		public static final int	cmiAutoCalUnit = 1121;
		
	// WLM Control Mode Constants
		public static final int	cCtrlWLMShow = 1;
		public static final int	cCtrlWLMHide = 2;
		public static final int	cCtrlWLMExit = 3;

	// Operation Mode Constants (for "Operation" and "GetOperationState" functions)
		public static final int	cStop = 0x0000;
		public static final int	cAdjustment = 0x0001;
		public static final int	cMeasurement = 0x0002;

	// Base Operation Constants (To be used exclusively, only one of this list at a time,
	// but still can be combined with "Measurement Action Addition Constants". See below.)
		public static final int	cCtrlStopAll = 0x0000;
		public static final int	cCtrlStartAdjustment = 0x0001;
		public static final int	cCtrlStartMeasurement = 0x0002;
		public static final int	cCtrlStartRecord = 0x0004;
		public static final int	cCtrlStartReplay = 0x0008;
		public static final int	cCtrlStoreArray = 0x0010;
		public static final int	cCtrlLoadArray = 0x0020;

	// Additional Operation Flag Constants (combine with "Base Operation Constants" above.)
		public static final int	cCtrlDontOverwrite = 0x0000;
		public static final int	cCtrlOverwrite = 0x1000;  // don't combine with cCtrlFileDialog
		public static final int	cCtrlFileGiven = 0x0000;
		public static final int	cCtrlFileDialog = 0x2000; // don't combine with cCtrlOverwrite and cCtrlFileASCII
		public static final int	cCtrlFileBinary = 0x0000; // *.smr, *.ltr
		public static final int	cCtrlFileASCII = 0x4000;  // *.smx, *.ltx, don't combine with cCtrlFileDialog

	// Measurement Control Mode Constants
		public static final int	cCtrlMeasDelayRemove = 0;
		public static final int	cCtrlMeasDelayGenerally = 1;
		public static final int	cCtrlMeasDelayOnce = 2;
		public static final int	cCtrlMeasDelayDenyUntil = 3;
		public static final int	cCtrlMeasDelayIdleOnce = 4;
		public static final int	cCtrlMeasDelayIdleEach = 5;
		public static final int	cCtrlMeasDelayDefault = 6;

	// Measurement Triggering Action Constants
		public static final int	cCtrlMeasurementContinue = 0;
		public static final int	cCtrlMeasurementInterrupt = 1;
		public static final int	cCtrlMeasurementTriggerPoll = 2;
		public static final int	cCtrlMeasurementTriggerSuccess = 3;

	// ExposureRange Constants
		public static final int	cExpoMin = 0;
		public static final int	cExpoMax = 1;
		public static final int	cExpo2Min = 2;
		public static final int	cExpo2Max = 3;

	// Amplitude Constants
		public static final int	cMin1 = 0;
		public static final int	cMin2 = 1;
		public static final int	cMax1 = 2;
		public static final int	cMax2 = 3;
		public static final int	cAvg1 = 4;
		public static final int	cAvg2 = 5;

	// Measurement Range Constants
		public static final int	cRange_250_410 = 4;
		public static final int	cRange_250_425 = 0;
		public static final int	cRange_300_410 = 3;
		public static final int	cRange_350_500 = 5;
		public static final int	cRange_400_725 = 1;
		public static final int	cRange_700_1100 = 2;
		public static final int	cRange_900_1500 = 6;
		public static final int	cRange_1100_1700 = 7;

	// Unit Constants for Get-/SetResultMode, GetLinewidth, Convert... and Calibration
		public static final int	cReturnWavelengthVac = 0;
		public static final int	cReturnWavelengthAir = 1;
		public static final int	cReturnFrequency = 2;
		public static final int	cReturnWavenumber = 3;
		public static final int	cReturnPhotonEnergy = 4;

	// Source Type Constants for Calibration
		public static final int	cHeNe633 = 0;
		public static final int	cHeNe1152 = 0;
		public static final int	cNeL = 1;
		public static final int	cOther = 2;
		public static final int	cFreeHeNe = 3;

	// Unit Constants for Autocalibration
		public static final int	cACOnceOnStart = 0;
		public static final int	cACMeasurements = 1;
		public static final int	cACDays = 2;
		public static final int	cACHours = 3;
		public static final int	cACMinutes = 4;
		
	// Pattern- and Analysis Constants
		public static final int	cPatternDisable = 0;
		public static final int	cPatternEnable = 1;
		public static final int	cAnalysisDisable = 0;
		public static final int	cAnalysisEnable = 1;

		public static final int	cSignal1Interferometers = 0;
		public static final int	cSignal1WideInterferometer = 1;
		public static final int	cSignal1Grating = 1;
		public static final int	cSignal2Interferometers = 2;
		public static final int	cSignal2WideInterferometer = 3;
		public static final int	cSignalAnalysis = 4;
		public static final int	cSignalAnalysisX = 4;
		public static final int	cSignalAnalysisY = 5;

	// Return errorvalues of GetFrequency, GetWavelength and GetWLMVersion
		public static final int	ErrNoValue = 0;
		public static final int	ErrNoSignal = -1;
		public static final int	ErrNoPulse = -8;
		public static final int	ErrBadSignal = -2;
		public static final int	ErrLowSignal = -3;
		public static final int	ErrBigSignal = -4;
		public static final int	ErrWlmMissing = -5;
		public static final int	ErrNotAvailable = -6;
		public static final int	InfNothingChanged = -7;
		public static final int	ErrDiv0 = -13;
		public static final int	ErrOutOfRange = -14;
		public static final int	ErrUnitNotAvailable = -15;
		public static final int	ErrMaxErr = -15;

	// Return errorvalues of GetTemperature
		public static final int	ErrTemperature = -1000;
		public static final int	ErrTempNotMeasured = -1000;
		public static final int	ErrTempNotAvailable = -1006;
		public static final int	ErrTempWlmMissing = -1005;

	// Return errorvalues of GetDistance
		// real errorvalues are ErrDistance combined with those of GetWavelength
		public static final int	ErrDistance = -1000000000;
		public static final int	ErrDistanceNotAvailable = -1000000006;
		public static final int	ErrDistanceWlmMissing = -1000000005;

	// *** end of wlmData.h

	
}

